/*
RetroLeague - Mobile application for The Retro League Podcast
Copyright (C) 2010-2013 Hugues Johnson

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software 
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

package com.huguesjohnson.retroleague.rss;

import java.util.ArrayList;
import java.util.Date;

import org.apache.commons.lang3.StringEscapeUtils;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import com.huguesjohnson.retroleague.StreamEntry;
import com.huguesjohnson.retroleague.StreamEntry.Sources;
import com.huguesjohnson.retroleague.util.BruteForceDateParser;

import android.util.Log;

public class RssParserHandler extends DefaultHandler{
	private final static String TAG="HeadlineParserHandler";
	private final static String TAG_ITEM="item";
	private final static String TAG_TITLE="title";
	private final static String TAG_DESCRIPTION="description";
	private final static String TAG_PUBDATE="pubDate";
	private final static String TAG_LINK="link";
	private ArrayList<StreamEntry> entryList=new ArrayList<StreamEntry>();
	private StreamEntry currentEntry=null;
    private StringBuilder characters=new StringBuilder();
    private boolean readThis=false;
	private boolean inItemBlock=false;
	private BruteForceDateParser dateParser;
    private Date minimumDate;
    private Sources source;

	public RssParserHandler(Date minimumDate,Sources source){
    	super();
    	this.minimumDate=minimumDate;
    	this.source=source;
    	this.dateParser=BruteForceDateParser.getInstance();
    }
    
	public ArrayList<StreamEntry> getEntryList(){
		return(this.entryList);
	}
	
	@Override
	public void startDocument() throws SAXException{
		super.startDocument();
	}

    @Override
    public void characters(char[] ch,int start,int length) throws SAXException{
        super.characters(ch,start,length);
        if(readThis){
        	this.characters.append(ch,start,length);
    	}
    }
	
	@Override
	public void startElement(String uri,String localName,String qName,Attributes attributes) throws SAXException{
		super.startElement(uri,localName,qName,attributes);
		try{
			String tagName=localName;
			if((tagName==null)||(tagName.length()<1)){
				tagName=qName;
			}
			if(tagName.equalsIgnoreCase(TAG_TITLE)){
				readThis=true;
				this.characters.setLength(0);
			}else if(tagName.equalsIgnoreCase(TAG_ITEM)){
				this.currentEntry=new StreamEntry();
				this.currentEntry.setSource(this.source);
				inItemBlock=true;
			}
			if(this.currentEntry!=null){
				if(tagName.equalsIgnoreCase(TAG_DESCRIPTION)){
					readThis=true;
					this.characters.setLength(0);
				}else if(tagName.equalsIgnoreCase(TAG_PUBDATE)){
					readThis=true;
					this.characters.setLength(0);
				}else if(tagName.equalsIgnoreCase(TAG_LINK)){
					readThis=true;
					this.characters.setLength(0);
				}
			}
		}catch(Exception x){
			Log.e(TAG,"startElement",x);
		}
	}

	@Override
	public void endElement(String uri,String localName,String qName) throws SAXException{
		super.endElement(uri,localName,qName);
		try{
			String tagName=localName;
			if((tagName==null)||(tagName.length()<1)){
				tagName=qName;
			}
			if(inItemBlock){
				if(tagName.equalsIgnoreCase(TAG_ITEM)){
					if(this.currentEntry.getPostedDate().compareTo(this.minimumDate)>0){
						this.entryList.add(this.currentEntry);
					}
					this.currentEntry=null;
					readThis=false;
					inItemBlock=false;
				}else if(tagName.equalsIgnoreCase(TAG_TITLE)){
					//check if this is the rss channel title or the item title
					if(this.currentEntry!=null){
						String title=this.characters.toString();
						if(this.source==Sources.Facebook){
							title=StringEscapeUtils.unescapeHtml4(title);
						}
						this.currentEntry.setTitle(title);
					}
					readThis=false;
				}else if(tagName.equalsIgnoreCase(TAG_DESCRIPTION)){
					//check if this is the rss channel description or the item description
					if(this.currentEntry!=null){
						//TODO - hack to ensure content is html, maybe look for a less hacky solution
						StringBuffer content=new StringBuffer(this.characters.toString());
						if((!content.substring(0,1).equals("<"))||(!content.substring(0,4).equals("&lt;"))){
							content.insert(0,"<p>");
							content.append("</p>");
						}
						this.currentEntry.setContent(content.toString());
					}
					readThis=false;
				}else if(tagName.equalsIgnoreCase(TAG_PUBDATE)){
					String sDate=this.characters.toString();
					this.currentEntry.setPostedDate(this.dateParser.parseDate(sDate));
					readThis=false;
				}else if(tagName.equalsIgnoreCase(TAG_LINK)){
					//check if this is the rss channel link or the item link
					if(this.currentEntry!=null){
						this.currentEntry.setUrl(this.characters.toString());
					}
					readThis=false;
				}				
			}else{
				if(tagName.equalsIgnoreCase(TAG_TITLE)){
					//don't care about the rss channel title
					readThis=false;
				}
			}
		}catch(Exception x){
			Log.e(TAG,"endElement",x);
		}
	}
	
}